package com.github.slowrookie.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Persistable;
import org.springframework.data.jpa.domain.Specification;

import com.github.slowrookie.persistence.AuditablePersistable;
import com.github.slowrookie.repository.DefaultRepository;
import com.github.slowrookie.service.DefaultCrudService;

/**
 * Crud的默认实现，减少不必要额代码量
 * 
 * @author 刘佳兴
 * @param <T>
 */
@Transactional
public abstract class DefaultCrudServiceImpl<T extends Persistable<Long>> implements DefaultCrudService<T>{
	
	protected DefaultRepository<T> defaultRepository = null;
	
	public DefaultCrudServiceImpl(DefaultRepository<T> defaultRepository) {
		super();
		this.defaultRepository = defaultRepository;
	}

	@Override
	public T findOne(Long id) {
		return defaultRepository.findOne(id);
	}

	@Override
	public T save(T auditable) {
		
		T persistEntity = auditable;
		
		if(!auditable.isNew()){
			persistEntity = defaultRepository.findOne(auditable.getId());
			BeanUtils.copyProperties(auditable, persistEntity, AuditablePersistable.ignoreProperties);
		}
		
		return defaultRepository.save(persistEntity);
	}

	@Override
	public List<T> save(Iterable<T> entities) {
		
		List<T> result = new ArrayList<T>();
		
		if (entities == null) {
			return result;
		}
		
		for (T entity : entities) {
			result.add(save(entity));
		}
		
		return result;
	}

	@Override
	public void delete(Long id) {
		defaultRepository.delete(id);
	}

	@Override
	public void detete(Iterable<T> entities) {
		defaultRepository.delete(entities);
	}
	
	@Override
	public List<T> findAll() {
		return defaultRepository.findAll();
	}

	@Override
	public List<T> findAll(Iterable<Long> ids) {
		return defaultRepository.findAll(ids);
	}

	@Override
	public List<T> findAll(Specification<T> entityQuery) {
		return defaultRepository.findAll(entityQuery);
	}

	@Override
	public Page<T> findAll(Specification<T> entityQuery, Pageable pageable) {
		return defaultRepository.findAll(entityQuery, pageable);
	}

	@Override
	public void deleteAllInBatch() {
		defaultRepository.deleteAllInBatch();
	}
	
	@Override
	public void deleteInBatch(Iterable<T> entities) {
		defaultRepository.deleteInBatch(entities);
	}

	@Override
	public void deleteAll() {
		defaultRepository.deleteAllInBatch();
	}

	@Override
	public boolean exists(Long id) {
		return defaultRepository.exists(id);
	}

	@Override
	public long count() {
		return defaultRepository.count();
	}

	@Override
	public long count(Specification<T> queryEntity) {
		return defaultRepository.count(queryEntity);
	}

	
}
